package com.xinggq.auth.service.config;

import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import io.swagger.v3.oas.models.servers.Server;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

/**
 * Swagger/OpenAPI 配置类
 * 配置API文档的基本信息、安全认证、服务器信息等
 *
 * @author xinggq
 * @since 2024-01-01
 */
@Configuration
@ConditionalOnProperty(name = "springdoc.api-docs.enabled", havingValue = "true", matchIfMissing = false)
public class SwaggerConfig {

    @Value("${server.port:8080}")
    private String serverPort;

    @Value("${server.servlet.context-path:}")
    private String contextPath;

    @Value("${spring.application.name:Auth Center Service}")
    private String applicationName;

    @Value("${app.version:1.0.0}")
    private String appVersion;

    /**
     * 配置OpenAPI文档信息
     */
    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
                .info(apiInfo())
                .servers(serverList())
                .components(securityComponents())
                .addSecurityItem(securityRequirement());
    }

    /**
     * API基本信息配置
     */
    private Info apiInfo() {
        return new Info()
                .title("Box 认证中心 API")
                .description(buildDescription())
                .version(appVersion)
                .contact(contactInfo())
                .license(licenseInfo());
    }

    /**
     * 构建API描述信息
     */
    private String buildDescription() {
        return """
                ## 📋 API概述
                
                Box认证中心提供统一的用户认证、授权管理和会话控制功能。
                采用现代化的双Token认证机制，确保系统安全性的同时提供良好的用户体验。
                
                ## 🔑 核心功能
                
                - **用户认证**：支持用户名/密码登录
                - **双Token机制**：Access Token + Refresh Token
                - **多端登录**：支持Web、移动端等多种客户端
                - **会话管理**：基于Redis的会话管理
                - **安全控制**：Token黑名单、防重放攻击
                
                ## 🛡️ 认证方式
                
                本API使用Bearer Token认证方式，请在请求头中添加：
                ```
                Authorization: Bearer {your_access_token}
                ```
                
                ## 📚 使用说明
                
                1. 首先调用登录接口获取Token
                2. 在后续请求中携带Access Token
                3. Token过期时使用Refresh Token刷新
                4. 登出时调用登出接口使Token失效
                
                ## 🔗 相关链接
                
                - [项目文档](https://github.com/xinggq/box/tree/main/box-auth-center/doc)
                - [认证架构设计](https://github.com/xinggq/box/blob/main/box-auth-center/doc/双Token认证机制设计文档.md)
                """;
    }

    /**
     * 联系人信息
     */
    private Contact contactInfo() {
        return new Contact()
                .name("xinggq")
                .email("xinggq@example.com")
                .url("https://github.com/xinggq");
    }

    /**
     * 许可证信息
     */
    private License licenseInfo() {
        return new License()
                .name("MIT License")
                .url("https://opensource.org/licenses/MIT");
    }

    /**
     * 服务器列表配置
     */
    private List<Server> serverList() {
        String serverUrl = "http://localhost:" + serverPort + contextPath;
        
        Server localServer = new Server()
                .url(serverUrl)
                .description("本地开发环境");

        Server testServer = new Server()
                .url("http://test-auth.example.com")
                .description("测试环境");

        Server prodServer = new Server()
                .url("https://auth.example.com")
                .description("生产环境");

        return List.of(localServer, testServer, prodServer);
    }

    /**
     * 安全组件配置
     */
    private Components securityComponents() {
        return new Components()
                .addSecuritySchemes("bearerAuth", bearerAuthScheme())
                .addSecuritySchemes("refreshToken", refreshTokenScheme());
    }

    /**
     * Bearer Token认证方案
     */
    private SecurityScheme bearerAuthScheme() {
        return new SecurityScheme()
                .type(SecurityScheme.Type.HTTP)
                .scheme("bearer")
                .bearerFormat("JWT")
                .description("请输入Access Token，格式：Bearer {token}");
    }

    /**
     * Refresh Token认证方案
     */
    private SecurityScheme refreshTokenScheme() {
        return new SecurityScheme()
                .type(SecurityScheme.Type.APIKEY)
                .in(SecurityScheme.In.HEADER)
                .name("Refresh-Token")
                .description("用于刷新Access Token的Refresh Token");
    }

    /**
     * 安全要求配置
     */
    private SecurityRequirement securityRequirement() {
        return new SecurityRequirement()
                .addList("bearerAuth");
    }
}